package br.org.game.mthread;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;

public class ConnectionSocket extends Thread {

	private static int numberOfConnections = 0;
	private Socket clientSocket;
	private DataInputStream input;
	private PrintStream output;
	private ServerWriter writer;

	public ConnectionSocket(ThreadGroup connectionsThreadGroup, Socket clienteSocket, ServerWriter writer, int priority) {
		super(connectionsThreadGroup, "Connection number" + numberOfConnections++);
		this.setPriority(priority);
		this.clientSocket = clienteSocket;
		this.writer = writer;
		try {
			// Atach the streams aos streams de entrada e saida do socket do
			// cliente e adiciona este outputstream ao vetor que contem todos
			// os streams de saida, usados pelo escritor writer
			input = new DataInputStream(clientSocket.getInputStream());
			output = new PrintStream(clientSocket.getOutputStream());
			writer.add(output);
		} catch (IOException streamIOException) {
			try {
				clientSocket.close();
			} catch (IOException closeSocketIOException) {
				System.err.println("Exception while getting socket streams:" + streamIOException);
				return;
			}
		}
		// dispara Thread
		this.start();
	}

	// O metodo run faz um laco lendo as mensagens recebidas
	@SuppressWarnings("deprecation")
	@Override
	public void run() {
		String inline;
		// Envia uma mensagem de boas vindas ao cliente
		output.println("Bem vindo ao MiniChat...");
		try {
			while (true) {
				// le uma linha de mensagem
				inline = input.readLine();
				// A conexao eh interrompida se null
				if (inline == null)
					break;
				// Joga a linha no escritor writer
				writer.setMessage(inline);
				synchronized (writer) {
					// chama o escritor synchronized() para evitar que duas linhas
					// Connection o chamem ao mesmo tempo. Esta e uma forma de "bloqueio".
					writer.notify();
				}
			}
		} catch (IOException e) {
			// TODO tratar
		} finally {
			try {
				clientSocket.close();
			} catch (IOException e2) {
				// TODO tratar
			}
		}
	}
}
